//===============================================================================
// Microsoft patterns & practices
// Guidance Explorer Offline Client
//===============================================================================
// Copyright  Microsoft Corporation.  All rights reserved.
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY
// OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT
// LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
// FITNESS FOR A PARTICULAR PURPOSE.
//===============================================================================

using System;
using System.Collections.Generic;
using System.Windows.Forms;
using GuidanceExplorer.Model;
using GuidanceExplorer.Model.Conditions;

namespace GuidanceExplorer.Controls
{
    /// <summary>
    /// The node for a single library.
    /// </summary>
    [MenuItemAttribute(500, "context\\New Item", GuidanceExplorer.Commands.NewGuidanceItem, typeof(ModelItemMenuItemIsEditableCondition), Keys.None)]
    [MenuItemAttribute(505, "context\\New Item Template", GuidanceExplorer.Commands.NewGuidanceItem, typeof(ModelItemMenuItemIsEditableCondition), typeof(NewItemMenuItemProvider), Keys.None)]
    [MenuItemAttribute(507, "context\\-", null, typeof(ModelItemMenuItemIsEditableCondition), Keys.None)]
    [MenuItemAttribute(510, "context\\New Folder", GuidanceExplorer.Commands.NewFolder, typeof(ModelItemMenuItemIsEditableCondition), Keys.None)]
    [MenuItemAttribute(515, "context\\New View", GuidanceExplorer.Commands.NewView, typeof(ModelItemMenuItemIsEditableCondition), Keys.None)]
    //[MenuItemAttribute(520, "context\\New Search View", GuidanceExplorer.Commands.NewSearchView, typeof(ModelItemMenuItemIsEditableCondition), Keys.None)]
//    [MenuItemAttribute(525, "context\\-", null, typeof(ModelItemMenuItemIsEditableCondition), Keys.None)]
    //[MenuItemAttribute(530, "context\\Save Library As...", GuidanceExplorer.Commands.SaveLibraryAs, Keys.None)]
    [MenuItemAttribute(535, "context\\-", null, typeof(ModelItemMenuItemIsEditableCondition), Keys.None)]
    [MenuItemAttribute(540, "context\\Import Item...", GuidanceExplorer.Commands.ImportGuidanceItemToLibrary, typeof(ModelItemMenuItemIsEditableCondition), Keys.None)]
    [MenuItemAttribute(550, "context\\Export Library...", GuidanceExplorer.Commands.ExportLibrary, Keys.None)]
    [MenuItemAttribute(555, "context\\-", null, typeof(ModelItemMenuItemIsEditableCondition), Keys.None)]
    [MenuItemAttribute(560, "context\\Rename Library", GuidanceExplorer.Commands.RenameLibrary, typeof(ModelItemMenuItemIsEditableCondition), Keys.None)]
    [MenuItemAttribute(565, "context\\Delete Library", GuidanceExplorer.Commands.DeleteLibrary, typeof(ModelItemMenuItemIsEditableCondition), Keys.None)]
    [MenuItemAttribute(570, "context\\-", null, typeof(OrGenericMenuItemCondition<WebSubscribedLibraryCondition,IsFileSubscribedLibraryCondition>), Keys.None)]
    //[MenuItemAttribute(573, "context\\Subscribe to RSS Feed", GuidanceExplorer.Commands.RSSSubscribe, typeof(WebSubscribedLibraryCondition), Keys.None)]
    [MenuItemAttribute(575, "context\\Synchronize Library", GuidanceExplorer.Commands.Synchronize, typeof(WebSubscribedLibraryCondition), Keys.None)]
    [MenuItemAttribute(580, "context\\Refresh Content", GuidanceExplorer.Commands.RefreshFileSubscribedLibrary, typeof(IsFileSubscribedLibraryCondition), Keys.None)]
    //[MenuItemAttribute(585, "context\\-", null, typeof(NotWebSubscribedLibraryCondition), Keys.None)]
    //[MenuItemAttribute(590, "context\\Publish Library", GuidanceExplorer.Commands.PublishLibrary, typeof(NotWebSubscribedLibraryCondition), Keys.None)]
    public class LibraryNode : ModelNode<Library>
    {
        private Dictionary<string, GuidanceTypeNode> _guidanceTypeNodes = new Dictionary<string, GuidanceTypeNode>();
        
        /// <summary>
        /// Factory.
        /// </summary>
        /// <returns></returns>
        public static LibraryNode New()
        {
            return new LibraryNode();
        }

        /// <summary>
        /// Default constructor.
        /// </summary>
        /// <param name="writeProtection">Defines the write protection of the library.</param>
        private LibraryNode()
            : base("<a library>", 2, 2)
        {
        }

        /// <summary>
        /// The Library instance.
        /// </summary>
        public override Library ModelInstance
        {
            set
            {
                base.ModelInstance = value;

                if (value.FileSubscribed || value.WebSubscribed)
                {
                    if (value.ReadProtection == ReadProtection.ReadOnly)
                    {
                        this.SelectedImageIndex = this.ImageIndex = 7;
                    }
                    else
                    {
                        this.SelectedImageIndex = this.ImageIndex = 6;
                    }
                }
                else
                {
                    if (value.ReadProtection == ReadProtection.ReadOnly)
                    {
                        this.SelectedImageIndex = this.ImageIndex = 3;
                    }
                    else
                    {
                        this.SelectedImageIndex = this.ImageIndex = 2;
                    }
                }
            }
        }

        /// <summary>
        /// Add a new GuidanceType node to the LibraryNode
        /// </summary>
        /// <param name="typeNode"></param>
        public void AddGuidanceTypeNode(GuidanceTypeNode typeNode)
        {
            string typeKey;

            if (string.IsNullOrEmpty(typeNode.ModelInstance.NodeDisplayName))
            {
                typeKey = typeNode.ModelInstance.Name;
            }
            else
            {
                typeKey = typeNode.ModelInstance.NodeDisplayName;
                typeNode.Text = typeKey;
            }

            _guidanceTypeNodes[typeKey] = typeNode;

            int i = 0;
            while (i < Nodes.Count && !(Nodes[i] is GuidanceTypeNode))
            {
                i++;
            }

            for (; i < Nodes.Count; i++)
            {
                if (string.Compare(typeNode.Text, Nodes[i].Text) < 0 || !(Nodes[i] is GuidanceTypeNode))
                {
                    break;
                }
            }

            Nodes.Insert(i, typeNode);
        }

        /// <summary>
        /// Removes the GuidanceType node for the specifies GuidanceType
        /// </summary>
        /// <param name="guidanceType"></param>
        public void RemoveGuidanceTypeNode(GuidanceType guidanceType)
        {
            string typeKey;

            if (string.IsNullOrEmpty(guidanceType.NodeDisplayName))
            {
                typeKey = guidanceType.Name;
            }
            else
            {
                typeKey = guidanceType.NodeDisplayName;
            }

            if (_guidanceTypeNodes.ContainsKey(typeKey))
            {
                Nodes.Remove(_guidanceTypeNodes[typeKey]);
                _guidanceTypeNodes[typeKey] = null;
            }
        }

        /// <summary>
        /// Return whether the LibraryNode contains a GuidanceType node for the specified GuidanceType
        /// </summary>
        /// <param name="guidanceType"></param>
        /// <returns></returns>
        public bool HasGuidanceTypeNode(GuidanceType guidanceType)
        {
            string typeKey;

            if (String.IsNullOrEmpty(guidanceType.NodeDisplayName))
            {
                typeKey = guidanceType.Name;
            }
            else
            {
                typeKey = guidanceType.NodeDisplayName;
            }

            return _guidanceTypeNodes.ContainsKey(typeKey) && _guidanceTypeNodes[typeKey] != null;
        }

        /// <summary>
        /// Whether the node is editable. ReadOnly libraries are not editable.
        /// </summary>
        public override bool IsEditable
        {
            get { return (ModelInstance.ReadProtection == ReadProtection.ReadWrite); }
        }

        public override bool CanDrop(IModelItem modelNode)
        {
            //If the library is read only, then all operations are cancelled.
            if (ModelInstance.ReadProtection == ReadProtection.ReadOnly)
            {
                return false;
            }

			MenuItemUnderSolutionNodeCondition isUnderSolutionNode = new MenuItemUnderSolutionNodeCondition();

            ViewNode viewNode = modelNode as ViewNode;
            FolderNode folderNode = modelNode as FolderNode;
            SearchViewNode searchNode = modelNode as SearchViewNode;
			ChecklistNode checkListNode = modelNode as ChecklistNode;

            if (viewNode != null)
            {
                /*
                 * Test for views:
                 *  The root views can't be droped in the library.
                 */
                //Root views cant be dragged
                if (viewNode.ModelInstance.RootView)
                {
                    return false;
                }

				if (isUnderSolutionNode.ShowMenuItem(null,viewNode))
				{
					return false;
				}

                if (Object.ReferenceEquals(viewNode.ModelInstance.Container, ModelInstance))
                {
                    return false;
                }

                return true;
            }
            else if (folderNode != null)
            {
                /*
                 * Test for folders:
                 *  The root folders can't be droped in the library.
                 */
                if (Object.ReferenceEquals(folderNode.ModelInstance.Container, ModelInstance))
                {
                    return false;
                }
				if (isUnderSolutionNode.ShowMenuItem(null,folderNode))
				{
					return false;
				}

                return true;
            }
            else if (searchNode != null)
            {
                //Root views cant be dragged
                if (searchNode.ModelInstance.RootView)
                {
                    return false;
                }

                return true;
            }
			else if (checkListNode != null)
			{
				if (isUnderSolutionNode.ShowMenuItem(null, checkListNode))
				{
					return false;
				}
				return true;
			}

            return false;
        }
        
        public GuidanceTypeNode GetGuidanceTypeNode(GuidanceType guidanceType)
        {
            string typeKey;
            if (String.IsNullOrEmpty(guidanceType.NodeDisplayName))
            {
                typeKey = guidanceType.Name;
            }
            else
            {
                typeKey = guidanceType.NodeDisplayName;
            }
            if ( _guidanceTypeNodes.ContainsKey(typeKey))
            {
                return _guidanceTypeNodes[typeKey];
            }
            return null;
        }
    }
}

